﻿using System;
using System.Collections.Generic;
using DataFiller.DataStorage.Extension.DataProvider;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DataFillerTest
{
    [TestClass]
    public class DataEvaluatorTest
    {
        object[] DataModel;
        protected DataEvaluator _evaluator;

        [TestInitialize]
        public void PrepareData()
        {
            _evaluator = new DataEvaluator();
            DataModel = new object[1];

            TestRow Model = new TestRow();
            Model.RowNumber = 8556;

            Model.Cells = new List<TestCell>();
            for (int i = 0; i < 100; i++)
            {
                TestCell TestData = new TestCell
                {
                    CellNumber = i,
                    Data = string.Format("Data {0}", i),
                    Style = string.Format("Style {0}", i),
                };

                TestData.TestProperty = new InnerType
                {
                    Property1 = i,
                    Property2 = new InnerType
                    {
                        Property1 = i * i,
                        Property2 = null,
                        Property3 = null
                    }
                };

                Model.Cells.Add(TestData);
            }

            DataModel[0] = Model;
        }

        /// <summary>
        /// [0]
        /// </summary>
        [TestMethod]
        public void PropertyPath1()
        {
            _evaluator.SetEvaluator("[0]", DataModel, null);

            var result = _evaluator.EvaluatedValue;
            Assert.IsNotNull(result);
        }

        /// <summary>
        /// [0].RowNumber
        /// </summary>
        [TestMethod]
        public void PropertyPath2()
        {
            _evaluator.SetEvaluator("[0].RowNumber", DataModel, null);

            var result = _evaluator.EvaluatedValue;
            Assert.IsTrue(result == 8556);
        }

        /// <summary>
        /// [0].Cells
        /// </summary>
        [TestMethod]
        public void PropertyPath3()
        {
            _evaluator.SetEvaluator("[0].Cells", DataModel, null);

            dynamic result = _evaluator.EvaluatedValue;
            Assert.IsTrue(result.Count == 100);
        }

        /// <summary>
        /// [0].Cells[0]
        /// </summary>
        [TestMethod]
        public void PropertyPath4()
        {
            _evaluator.SetEvaluator("[0].Cells[0]", DataModel, null);

            dynamic result = _evaluator.EvaluatedValue;
            Assert.IsNotNull(result);
        }

        /// <summary>
        /// [0].Cells[(0)].CellNumber  in whic (0) = 3
        /// </summary>
        [TestMethod]
        public void PropertyPath5()
        {
            _evaluator.SetEvaluator("[0].Cells[(0)].CellNumber", DataModel, "", 3);

            dynamic result = _evaluator.EvaluatedValue;
            Assert.AreEqual(result, 3);
        }

        /// <summary>
        /// [0].Cells[10].CellNumber
        /// </summary>
        [TestMethod]
        public void PropertyPath6()
        {
            _evaluator.SetEvaluator("[0].Cells[10].CellNumber", DataModel, null);

            dynamic result = _evaluator.EvaluatedValue;
            Assert.AreNotEqual(result, 0);
        }

        [TestMethod]
        public void AccessorGenerator_Test()
        {
            InnerType tr = new InnerType
            {
                Property1 = 1,
                Property2 = new InnerType { Property1 = 2 }
            };

            var method = _evaluator.GetType().GetMethod("AccessorGenerator", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
            Delegate resultDelegate = (Delegate)method.MakeGenericMethod(typeof(InnerType)).Invoke(_evaluator, new object[] { new string[] { "Property2", "Property1" } });
            var result = resultDelegate.DynamicInvoke(tr);
            Assert.AreEqual(result, 2);
        }

        /// <summary>
        /// [0].Cells&CellNumber
        /// </summary>
        [TestMethod]
        public void PropertyPath7()
        {
            _evaluator.SetEvaluator("[0].Cells&CellNumber", DataModel, "&");
            dynamic result = _evaluator.EvaluatedValue;
        }

        /// <summary>
        /// [0].Cells&TestProperty.Property1
        /// </summary>
        [TestMethod]
        public void PropertyPath8()
        {
            _evaluator.SetEvaluator(" [0].Cells&TestProperty.Property1", DataModel, "&");
            dynamic result = _evaluator.EvaluatedValue;
            foreach (var item in result)
            {
                
            }
            Assert.IsNotNull(result);
        }
    }

   
}
